package cn.learn.validate.image;

import cn.learn.validate.impl.AbstractValidateCodeProcessor;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 图形验证码的处理器
 *
 * @author huangyezhan
 * @date 2020年02月21日12:13
 */
@Component
public class ImageValidateCodeProcessor extends AbstractValidateCodeProcessor<ImageCode> {
    private static final Logger logger = LoggerFactory.getLogger(ImageValidateCodeProcessor.class);

    /**
     * 发送图形验证码给用户
     *
     * @param response     响应
     * @param validateCode 验证码的相关消息
     */
    @Override
    protected void send(HttpServletResponse response, ImageCode validateCode) {
        try (ServletOutputStream outputStream = response.getOutputStream()) {
            ImageIO.write(validateCode.getImage(), "jpg", outputStream);
        } catch (IOException e) {
            logger.info("验证码输出流错误", e);
        }
    }

    /**
     * 覆写保存session方法的原因：
     * 1、不存图片进session；
     * 2、session已经存在；
     *
     * @param request      请求
     * @param validateCode 验证码的对象
     */
    @Override
    protected void save(HttpServletRequest request, ImageCode validateCode) {
        //如果session没有指定属性，则直接存进session里面，如果session里面有值，则更改值
        String    sessionKey  = this.getSessionKey(request);
        ImageCode sessionCode = (ImageCode) request.getSession().getAttribute(sessionKey);
        if (sessionCode == null) {
            //用json克隆新对象
            String s = JSON.toJSONString(validateCode);
            sessionCode = JSON.parseObject(s, ImageCode.class);
            logger.info("sessionId{}克隆ImageCode对象成功{}，准备保存对象", request.getSession().getId(), s);
            super.save(request, sessionCode);
        } else {
            String    accountName = request.getParameter("username");
            logger.info("sessionId{}的验证码已经刷新的次数{},验证过了的次数{}", request.getSession().getId(), sessionCode.getRefreshNum(), sessionCode.getValidateNum());
            sessionCode.setCode(validateCode.getCode());
            sessionCode.setExpireTime(validateCode.getExpireTime());
            sessionCode.setTotalValidations(validateCode.getTotalValidations());
            sessionCode.setValidateNum(validateCode.getValidateNum());
            sessionCode.setRefreshNum(sessionCode.getRefreshNum() + 1);
        }
    }
}
